#ifndef _SYS_FILE_H_
#define _SYS_FILE_H_

#include "FanObj.h"
#include "SysTypes.h"

#define FILE_VTABLE(self)   ((FileVTable*)((FanObj*)self)->vtable)


extern Type*    File_classType;
extern VTable*  File_classVTable;


/* [sys::File] Attributes */
struct File
{
  FanObj        super;
};


/* [sys::File] Virtual-table */
typedef struct FileVTable
{
  FanObjVTable  super;
  File*         (*copyInto_1)(File* self, File* dir);
  File*         (*copyInto)(File* self, File* dir, Map* options);
  File*         (*copyTo_1)(File* self, File* to);
  File*         (*copyTo)(File* self, File* to, Map* options);
  File*         (*create)(File* self);
  void          (*delete)(File* self);
  File*         (*deleteOnExit)(File* self);
  Bool          (*exists)(File* self);
  InStream*     (*in_0)(File* self);
  InStream*     (*in)(File* self, NullableInt bufferSize);
  List*         (*list)(File* self);
  List*         (*listDirs)(File* self);
  List*         (*listFiles)(File* self);
  Buf*          (*mmap_0)(File* self);
  Buf*          (*mmap_1)(File* self, Str* mode);
  Buf*          (*mmap_2)(File* self, Str* mode, Int pos);
  Buf*          (*mmap)(File* self, Str* mode, Int pos, NullableInt size);
  DateTime*     (*modified)(File* self);
  void          (*setModified)(File* self, DateTime* val);
  File*         (*moveInto)(File* self, File* dir);
  File*         (*moveTo)(File* self, File* to);
  File*         (*normalize)(File* self);
  Buf*          (*open_0)(File* self);
  Buf*          (*open)(File* self, Str* mode);
  Str*          (*osPath)(File* self);
  OutStream*    (*out_0)(File* self);
  OutStream*    (*out_1)(File* self, Bool append);
  OutStream*    (*out)(File* self, Bool append, NullableInt bufferSize);
  File*         (*parent)(File* self);
  File*         (*plus_1)(File* self, Uri* path);
  File*         (*plus)(File* self, Uri* path, Bool checkSlash);
  File*         (*rename)(File* self, Str* newName);
  NullableInt   (*size)(File* self);
  void          (*walk)(File* self, Func* c);
} FileVTable;


/* [sys::File] Methods and fields */
void            File_makeNew(File* self, Uri* uri);
Bool            File_equals(Obj self, NullableObj that);
Int             File_hash(Obj self);
Str*            File_toStr(Obj self);
DateTime*       File_modified(File* self);
void            File_setModified(File* self, DateTime* val);
Str*            File_sep(void);
Str*            File_pathSep(void);
File*           File_make_1(Uri* uri);
File*           File_make(Uri* uri, Bool checkSlash);
File*           File_os(Str* osPath);
List*           File_osRoots(void);
File*           File_createTemp_0(void);
File*           File_createTemp_1(Str* prefix);
File*           File_createTemp_2(Str* prefix, Str* suffix);
File*           File_createTemp(Str* prefix, Str* suffix, File* dir);
Uri*            File_uri(File* self);
Bool            File_isDir(File* self);
List*           File_path(File* self);
Str*            File_pathStr(File* self);
Str*            File_name(File* self);
Str*            File_basename(File* self);
Str*            File_ext(File* self);
MimeType*       File_mimeType(File* self);
Bool            File_exists(File* self);
NullableInt     File_size(File* self);
Str*            File_osPath(File* self);
File*           File_parent(File* self);
List*           File_list(File* self);
List*           File_listDirs(File* self);
List*           File_listFiles(File* self);
void            File_walk(File* self, Func* c);
File*           File_normalize(File* self);
File*           File_plus_1(File* self, Uri* path);
File*           File_plus(File* self, Uri* path, Bool checkSlash);
File*           File_create(File* self);
File*           File_createFile(File* self, Str* name);
File*           File_createDir(File* self, Str* name);
File*           File_copyTo_1(File* self, File* to);
File*           File_copyTo(File* self, File* to, Map* options);
File*           File_copyInto_1(File* self, File* dir);
File*           File_copyInto(File* self, File* dir, Map* options);
File*           File_moveTo(File* self, File* to);
File*           File_moveInto(File* self, File* dir);
File*           File_rename(File* self, Str* newName);
void            File_delete(File* self);
File*           File_deleteOnExit(File* self);
Buf*            File_open_0(File* self);
Buf*            File_open(File* self, Str* mode);
Buf*            File_mmap_0(File* self);
Buf*            File_mmap_1(File* self, Str* mode);
Buf*            File_mmap_2(File* self, Str* mode, Int pos);
Buf*            File_mmap(File* self, Str* mode, Int pos, NullableInt size);
InStream*       File_in_0(File* self);
InStream*       File_in(File* self, NullableInt bufferSize);
OutStream*      File_out_0(File* self);
OutStream*      File_out_1(File* self, Bool append);
OutStream*      File_out(File* self, Bool append, NullableInt bufferSize);
Buf*            File_readAllBuf(File* self);
List*           File_readAllLines(File* self);
void            File_eachLine(File* self, Func* f);
Str*            File_readAllStr_0(File* self);
Str*            File_readAllStr(File* self, Bool normalizeNewlines);
Map*            File_readProps(File* self);
void            File_writeProps(File* self, Map* props);
NullableObj     File_readObj_0(File* self);
NullableObj     File_readObj(File* self, Map* options);
void            File_writeObj_1(File* self, NullableObj obj);
void            File_writeObj(File* self, NullableObj obj, Map* options);


/* [sys::File] Type-system functions */
Type*           File_initType(void);
VTable*         File_initVTable(void);
void            File_initStatic(void);


#endif
